<!DOCTYPE html>
<!--
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.
--><html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no, width=device-width">
<meta name="generator" content="joDoc">
<title>Apache Cordova API Documentation</title>
<link rel="stylesheet" type="text/css" href="index.css">
<link rel="stylesheet" type="text/css" href="mobile.css" media="only screen and (max-device-width: 1024px)">
<link rel="stylesheet" type="text/css" href="prettify/prettify.css">
</head>
<body>
        <div id="header">
            <h1><a href="index.html">Apache <strong>Cordova</strong> Documentation</a></h1>
            <small>
                <select><optgroup label="English" value="en">
<option value="edge">edge</option>
<option value="2.2.0rc2">2.2.0rc2</option>
<option value="2.2.0rc1">2.2.0rc1</option>
<option selected value="2.2.0">2.2.0</option>
<option value="2.1.0rc2">2.1.0rc2</option>
<option value="2.1.0rc1">2.1.0rc1</option>
<option value="2.1.0">2.1.0</option>
<option value="2.0.0rc1">2.0.0rc1</option>
<option value="2.0.0">2.0.0</option>
<option value="1.9.0rc1">1.9.0rc1</option>
<option value="1.9.0">1.9.0</option>
<option value="1.8.1">1.8.1</option>
<option value="1.8.0rc1">1.8.0rc1</option>
<option value="1.8.0">1.8.0</option>
<option value="1.7.0rc1">1.7.0rc1</option>
<option value="1.7.0">1.7.0</option>
<option value="1.6.1">1.6.1</option>
<option value="1.6.0rc1">1.6.0rc1</option>
<option value="1.6.0">1.6.0</option>
<option value="1.5.0rc1">1.5.0rc1</option>
<option value="1.5.0">1.5.0</option>
<option value="1.4.1">1.4.1</option>
<option value="1.4.0rc1">1.4.0rc1</option>
<option value="1.4.0">1.4.0</option>
<option value="1.3.0">1.3.0</option>
<option value="1.2.0">1.2.0</option>
<option value="1.1.0">1.1.0</option>
<option value="1.0.0rc3">1.0.0rc3</option>
<option value="1.0.0rc2">1.0.0rc2</option>
<option value="1.0.0rc1">1.0.0rc1</option>
<option value="1.0.0">1.0.0</option>
<option value="0.9.6">0.9.6</option>
<option value="0.9.5.1">0.9.5.1</option>
<option value="0.9.5">0.9.5</option>
<option value="0.9.4">0.9.4</option>
<option value="0.9.3">0.9.3</option>
<option value="0.9.2">0.9.2</option>
</optgroup>
<optgroup label="Español" value="es"><option value="1.0.0">1.0.0</option></optgroup>
<optgroup label="Français" value="fr">
<option value="1.3.0">1.3.0</option>
<option value="1.2.0">1.2.0</option>
<option value="1.1.0">1.1.0</option>
</optgroup>
<optgroup label="Japanese" value="jp">
<option value="2.0.0">2.0.0</option>
<option value="1.9.0">1.9.0</option>
<option value="1.8.1">1.8.1</option>
<option value="1.7.0">1.7.0</option>
<option value="0.9.5">0.9.5</option>
</optgroup>
<optgroup label="Korean" value="kr"><option value="2.0.0">2.0.0</option></optgroup></select></small>
        </div>
        <div id="subheader">
            <h1>Developing a Plugin on iOS</h1>
            <small><select><option value="Developing%2520a%2520Plugin%2520on%2520iOS">Developing a Plugin on iOS</option>
<option value="Developing%20a%20Plugin%20on%20iOS_plugin_class_mapping">      - Plugin Class Mapping</option>
<option value="Developing%20a%20Plugin%20on%20iOS_writing_an_ios_cordova_plugin">      - Writing an iOS Cordova Plugin</option>
<option value="Developing%20a%20Plugin%20on%20iOS_plugin_signatures">      - Plugin Signatures</option>
<option value="Developing%20a%20Plugin%20on%20iOS_echo_plugin_ios_plugin">      - Echo Plugin iOS Plugin</option>
<option value="Developing%20a%20Plugin%20on%20iOS_threading">      - Threading</option>
<option value="Developing%20a%20Plugin%20on%20iOS_advanced_plugin_functionality">      - Advanced Plugin Functionality</option>
<option value="Developing%20a%20Plugin%20on%20iOS_debugging_plugins">      - Debugging Plugins</option>
<option value="Developing%20a%20Plugin%20on%20iOS_common_pitfalls">      - Common Pitfalls</option>
<option value="Developing%20a%20Plugin%20on%20iOS_deprecated_plugin_signature_note">      - Deprecated Plugin Signature Note</option></select></small>
        </div>

        <div id="sidebar">
            <div class="vertical_divider"></div>
        <h1>API Reference</h1>
<ul>
<li><a href="cordova_accelerometer_accelerometer.md.html#Accelerometer">Accelerometer</a></li>
<li><a href="cordova_camera_camera.md.html#Camera">Camera</a></li>
<li><a href="cordova_media_capture_capture.md.html#Capture">Capture</a></li>
<li><a href="cordova_compass_compass.md.html#Compass">Compass</a></li>
<li><a href="cordova_connection_connection.md.html#Connection">Connection</a></li>
<li><a href="cordova_contacts_contacts.md.html#Contacts">Contacts</a></li>
<li><a href="cordova_device_device.md.html#Device">Device</a></li>
<li><a href="cordova_events_events.md.html#Events">Events</a></li>
<li><a href="cordova_file_file.md.html#File">File</a></li>
<li><a href="cordova_geolocation_geolocation.md.html#Geolocation">Geolocation</a></li>
<li><a href="cordova_globalization_globalization.md.html#Globalization">Globalization</a></li>
<li><a href="cordova_media_media.md.html#Media">Media</a></li>
<li><a href="cordova_notification_notification.md.html#Notification">Notification</a></li>
<li><a href="cordova_splashscreen_splashscreen.md.html#Splashscreen">Splashscreen</a></li>
<li><a href="cordova_storage_storage.md.html#Storage">Storage</a></li>
</ul>
<h1>Guides</h1>
<ul>
<li><a href="guide_getting-started_index.md.html#Getting%20Started%20Guides">Getting Started Guides</a></li>
<li><a href="guide_command-line_index.md.html#Command-Line%20Usage">Command-Line Usage</a></li>
<li><a href="guide_upgrading_index.md.html#Upgrading%20Guides">Upgrading Guides</a></li>
<li><a href="guide_project-settings_index.md.html#Project%20Settings">Project Settings</a></li>
<li><a href="guide_plugin-development_index.md.html#Plugin%20Development%20Guide">Plugin Development Guide</a></li>
<li><a href="guide_whitelist_index.md.html#Domain%20Whitelist%20Guide">Domain Whitelist Guide</a></li>
<li><a href="guide_cordova-webview_index.md.html#Embedding%20WebView">Embedding WebView</a></li>
<li><a href="_index.html">Keyword Index</a></li>
</ul>
</div>

        <div id="scrollable">
            <div id="content">
                <h1><a name="Developing%20a%20Plugin%20on%20iOS">Developing a Plugin on iOS</a></h1>

<p>A plugin is an Objective-C class that extends the <code>CDVPlugin</code> class.</p>

<p>Each plugin class must be registered using the Cordova.plist file, under the Plugins key.</p>

<h2>
<a name="Developing%20a%20Plugin%20on%20iOS_plugin_class_mapping">Plugin Class Mapping</a>
</h2>

<p>The JavaScript portion of a plugin always uses the <code>cordova.exec</code> method as follows:</p>

<pre class="prettyprint"><code>exec(&lt;successFunction&gt;, &lt;failFunction&gt;, &lt;service&gt;, &lt;action&gt;, [&lt;args&gt;]);
</code></pre>

<p>This will marshall a request from the UIWebView to the iOS native side, more or less boiling down to calling the <code>action</code> method on the <code>service</code> class, with the arguments passed in the <code>args</code> Array. </p>

<p>Plugins with long-running requests, background activity (e.g. playing media), listeners or internal state should implement the <code>onReset</code> method and stop or clean up those activities. This method is run when the <code>UIWebView</code> navigates to a new page or refreshes, which reloads the Javascript.</p>

<p>The plugin must be added to <code>Plugins</code> key (a Dictionary) of the <code>Cordova.plist</code> file in your Cordova-iOS application's project folder.</p>

<pre class="prettyprint"><code>&lt;key&gt;service_name&lt;/key&gt;
&lt;string&gt;PluginClassName&lt;/string&gt;
</code></pre>

<p>The key <code>service_name</code> should match what you use in the JavaScript <code>exec</code> call, and the value will be the name of the Objective-C class of the plugin. Without this added, the plugin may compile but will not be reachable by Cordova.</p>

<h2>
<a name="Developing%20a%20Plugin%20on%20iOS_writing_an_ios_cordova_plugin">Writing an iOS Cordova Plugin</a>
</h2>

<p>We have JavaScript fire off a plugin request to the native side. We have the iOS Objective-C plugin mapped properly via the <code>Cordova.plist</code> file. So what does the final iOS Objective-C Plugin class look like?</p>

<p>What gets dispatched to the plugin via JavaScript's <code>exec</code> function gets passed into the corresponding Plugin class's <code>action</code> method. A plugin method has this signature:</p>

<pre class="prettyprint"><code>- (void)myMethod:(CDVInvokedUrlCommand*)command
{
    CDVPluginResult* pluginResult = nil;
    NSString* myarg = [command.arguments objectAtIndex:0];

    if (myarg != nil) {
        pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK];
    } else { 
        pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR messageAsString:@"Arg was null"];
    }
    [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}
</code></pre>

<ol>
<li><a class="external" href="https://github.com/apache/incubator-cordova-ios/blob/master/CordovaLib/Classes/CDVInvokedUrlCommand.h">CDVInvokedUrlCommand.h</a></li>
<li><a class="external" href="https://github.com/apache/incubator-cordova-ios/blob/master/CordovaLib/Classes/CDVPluginResult.h">CDVPluginResult.h</a></li>
<li><a class="external" href="https://github.com/apache/incubator-cordova-ios/blob/master/CordovaLib/Classes/CDVCommandDelegate.h">CDVCommandDelegate.h</a></li>
</ol>
<h2>
<a name="Developing%20a%20Plugin%20on%20iOS_plugin_signatures">Plugin Signatures</a>
</h2>

<p>The <strong>new signature</strong> supported beginning in <strong>Cordova 2.1.0</strong> is:</p>

<pre class="prettyprint"><code>    - (void)myMethod:(CDVInvokedUrlCommand*)command;
</code></pre>

<p>The <strong>old (deprecated)</strong> signature is:</p>

<pre class="prettyprint"><code>    - (void)myMethod:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
</code></pre>

<p>Basically, the options dictionary has been removed for the new signature, and the callbackId is not the 0th index item for the arguments array, but it is now in a separate property. </p>

<h2>
<a name="Developing%20a%20Plugin%20on%20iOS_echo_plugin_ios_plugin">Echo Plugin iOS Plugin</a>
</h2>

<p>We would add the following to the <code>Plugins</code> key (a Dictionary) of the project's <code>Cordova.plist</code> file:</p>

<pre class="prettyprint"><code>&lt;key&gt;Echo&lt;/key&gt;
&lt;string&gt;Echo&lt;/string&gt;
</code></pre>

<p>Then we would add the following files (<code>Echo.h</code> and <code>Echo.m</code>) to the Plugins folder inside our Cordova-iOS
application folder:</p>

<pre class="prettyprint"><code>/********* Echo.h Cordova Plugin Header *******/

#import &lt;Cordova/CDV.h&gt;

@interface Echo : CDVPlugin

- (void)echo:(CDVInvokedUrlCommand*)command;

@end

/********* Echo.m Cordova Plugin Implementation *******/

#import "Echo.h"
#import &lt;Cordova/CDV.h&gt;

@implementation Echo

- (void)echo:(CDVInvokedUrlCommand*)command
{
    CDVPluginResult* pluginResult = nil;
    NSString* echo = [command.arguments objectAtIndex:0];

    if (echo != nil &amp;&amp; [echo length] &gt; 0) {
        pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:echo];
    } else {
        pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_ERROR];
    }

    [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}

@end
</code></pre>

<p>Let's take a look at the code. At the top we have all of the necessary Cordova imports. Our class extends from <code>CDVPlugin</code> - very important. </p>

<p>This plugin only supports one action, the <code>echo</code> action. First, we grab the echo string using the <code>objectAtIndex</code> method on our <code>args</code>, telling it we want to get the 0th parameter in the arguments array. We do a bit of parameter checking: make sure it is not <code>nil</code>, and make sure it is not a zero-length string.</p>

<p>If it is, we return a <code>PluginResult</code> with an <code>ERROR</code> status. If all of those checks pass, then we return a <code>PluginResult</code> with an <code>OK</code> status, and pass in the <code>echo</code> string we received in the first place as a parameter.</p>

<p>Finally, we send the result to <code>self.commandDelegate</code>, which will execute the JavaScript that will callback to success or failure callbacks of the exec method on the JavaScript side. If the success callback was called, it will pass the <code>echo</code> parameter as a parameter.</p>

<h2>
<a name="Developing%20a%20Plugin%20on%20iOS_threading">Threading</a>
</h2>

<p>Although UIWebViews run on a dedicated thread, plugin methods are executed on the UI thread. If your plugin requires a non-trivial amount of processing or requires a blocking call, you should make use of a background thread. An example:</p>

<pre class="prettyprint"><code>- (void)myPluginMethod:(CDVInvokedUrlCommand*)command
{
    // Check command.arguments here.
    [self.commandDelegate runInBackground:^{
        NSString* payload = nil;
        // Some blocking logic...
        CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:payload];
        // The sendPluginResult method is thread-safe.
        [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
    }];
}
</code></pre>

<h2>
<a name="Developing%20a%20Plugin%20on%20iOS_advanced_plugin_functionality">Advanced Plugin Functionality</a>
</h2>

<p>See other methods that you can override in:</p>

<ol>
<li><a class="external" href="https://github.com/apache/incubator-cordova-ios/blob/master/CordovaLib/Classes/CDVPlugin.h">CDVPlugin.h</a></li>
<li><a class="external" href="https://github.com/apache/incubator-cordova-ios/blob/master/CordovaLib/Classes/CDVPlugin.m">CDVPlugin.m</a></li>
</ol>
<p>For example, you can hook into the <a href="cordova_events_events.md.html#pause">pause</a>, <a href="cordova_events_events.md.html#resume">resume</a>, app terminate and handleOpenURL events.</p>

<h2>
<a name="Developing%20a%20Plugin%20on%20iOS_debugging_plugins">Debugging Plugins</a>
</h2>

<p>To debug the Objective-C side, you would use Xcode's built in debugger. For JavaScript, on iOS 5.0 you can use <a class="external" href="https://github.com/apache/incubator-cordova-weinre">Weinre, an Apache Cordova Project</a> or <a class="external" href="http://www.iwebinspector.com/">iWebInspector, a third-party utility</a></p>

<p>For iOS 6, you would use Safari 6.0 to simply attach to your app running in the iOS 6 Simulator.</p>

<h2>
<a name="Developing%20a%20Plugin%20on%20iOS_common_pitfalls">Common Pitfalls</a>
</h2>

<ul>
<li>Don't forget to add your plugin's mapping to Cordova.plist - if you forgot, an error will be printed to the Xcode console log</li>
<li>Don't forget to add any hosts you connect to in the <a href="guide_whitelist_index.md.html#Domain%20Whitelist%20Guide">whitelist</a> - if you forgot, an error will be printed to the Xcode console log</li>
</ul>
<h2>
<a name="Developing%20a%20Plugin%20on%20iOS_deprecated_plugin_signature_note">Deprecated Plugin Signature Note</a>
</h2>

<p>The <strong>old (deprecated)</strong> signature is:</p>

<pre class="prettyprint"><code>    - (void) myMethod:(NSMutableArray*)arguments withDict:(NSMutableDictionary*)options;
</code></pre>

<p>The options parameter for the Objective-C plugin method is being deprecated, and it should not be used. For legacy reasons - the last JavaScript object passed in the args Array will be passed in as the options dictionary of the method in Objective-C. You must make sure that any JavaScript object that is passed in as an element in the args array occurs as the last item in the Array, if not it will throw off the array index of all subsequent parameters of the Array in Objective-C. Only one JavaScript object is supported for the options dictionary, and only the last one encountered will be passed to the native method. It is because of these error-prone reasons that they are being deprecated.</p>

            </div>
        </div>

        <!-- Functionality and Syntax Highlighting -->
        <script type="text/javascript" src="index.js"></script><script type="text/javascript" src="prettify/prettify.js"></script>
</body>
</html>
